package com.ldd.malphite.interceptor;

import com.ldd.malphite.annotation.AccessLimit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.time.Duration;

@Slf4j
@Component
public class AccessInterceptor implements HandlerInterceptor {

    private final static String count = "COUNT:";
    private final static String lock = "LOCK:";

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.error("~~~~~~"+requestURI);
        if (requestURI.contains("favicon.ico")){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        AccessLimit methodAnnotation = handlerMethod.getMethodAnnotation(AccessLimit.class);
        if (methodAnnotation==null){
            log.error("~~~~~~~~~~~~~~~该接口不受访问限制~~~~~~~~~~~~~~~~~~~");
            return true;
        }else {
            Object o1 = redisTemplate.opsForValue().get(lock + requestURI);
            if (o1!=null){
                log.error("~~~~~~~~~~~~~~~该接口当前可以访问~~~~~~~~~~~~~~~~~~~");
                //设置返回类型和编码，否则会乱码
                response.setContentType("text/html;charset=utf-8");
                PrintWriter writer = response.getWriter();
                response.sendRedirect("");
                writer.write("<h1 style='color:red'>访问过于频繁,请稍后再试！</h1>");
                return false;
            }
            Object o = redisTemplate.opsForValue().get(count + requestURI);
            if(o==null){
                log.error("~~~~~~~~~~~~~~~该接口当前可以访问~~~~~~~~~~~~~~~~~~~");
                redisTemplate.opsForValue().set(count + requestURI,1);
                return true;
            }else {
                String s = (String)o;
                int queryCount = Integer.valueOf(s);
                if (queryCount+1>=5){
                    redisTemplate.delete(count + requestURI);
                    redisTemplate.opsForValue().set(lock + requestURI, "(?.?)",Duration.ofMinutes(1));
                }else {
                    redisTemplate.opsForValue().increment(count + requestURI);
                }
                return true;
            }
        }
    }
}
